David A. Wagner wrote: > > ObBug: if you use the SunOS tmpfs, try > > cd /tmp; /usr/etc/mknod fifo p; ln fifo link; ls -ClFg link fifo > > ...but not at peak hours! > > Sun knows about it and after a year, there's still no fix. [As > far as I know -- if there's one, I'd love to hear of it, so I can > tell the computer center here to add the darn thing: after hearing > of this one, they hacked the kernel and removed the mkfifo and > mknod S_IFIFO system calls. <sigh>] Here is our workaround for this. The problem is that for a special file, tmp_link() tries to update the link count (va_nlink in vattr) in the snode's vnode, rather than the real vnode. We take no responsibility for this code; it was developed without any source. Read it through and then use it if you like it. It works for us on SunOS 4.1.1 on a Sun3. Not tested on anything else. If you do use it, we'd be interested to hear whether or not it works for you. Please mail 8lgm@bagpuss.demon.co.uk. To use this, create the following program - 8lgm_tmpfs.c. Then compile and load using the commands described in the header comment. 8<------------------------- cut here ------------------------- /* * 8lgm_tmpfs.c - SunOS 4.1.x TMPFS bugfix. * Copyright (C) 1994 by [8LGM]. * * This works around a fatal bug in tmpfs, reported to Bugtraq * by dawagner@phoenix.princeton.edu (David A. Wagner) on 2/11/94. * * Bug: * cd /tmp; /usr/etc/mknod fifo p; ln fifo link; ls -ClFg link fifo * panics the kernel with a bus error. * * To use: * cc -c -O -DKERNEL -D<kernel-arch> 8lgm_tmpfs.c * modload 8lgm_tmpfs.o */ #include <sys/types.h> #include <sys/conf.h> #include <sys/buf.h> #include <sys/param.h> #include <sys/errno.h> #include <sys/user.h> #include <sys/time.h> #include <sys/vfs.h> #include <sys/vnode.h> #include <sys/ucred.h> #include <sys/syslog.h> #include <sundev/mbvar.h> #include <sun/autoconf.h> #include <sun/vddrv.h> extern struct vnodeops tmp_vnodeops; struct vdldrv vd; int (*real_tmp_link)(); int loaded_8lgm = 0; int tmp_link_8lgm(vn, dirp, name, cred) struct vnode *vn; struct vnode *dirp; char *name; struct ucred*cred; { struct vnode *real_vn; if (!(VOP_REALVP(vn, &real_vn))) vn = real_vn; return ((real_tmp_link)(vn, dirp, name, cred)); } int load_8lgm_tmpfsfix() { int x; x = splhigh(); real_tmp_link = tmp_vnodeops.vn_link; tmp_vnodeops.vn_link = tmp_link_8lgm; splx(x); return(0); } int unload_8lgm_tmpfsfix() { int x; x = splhigh(); tmp_vnodeops.vn_link = real_tmp_link; splx(x); return(0); } int xxxinit(function_code, vdp, vdi, vds) unsigned int function_code; struct vddrv *vdp; addr_t vdi; struct vdstat *vds; { bzero(&vd, sizeof(vd)); vd.Drv_magic = VDMAGIC_PSEUDO; vd.Drv_name = "8lgm-tmpfs"; switch(function_code) { case VDLOAD: if (loaded_8lgm) { log(LOG_INFO, "8lgm: tmpfs fix module loaded\n"); return(EEXIST); } vdp->vdd_vdtab = (struct vdlinkage*)&vd; load_8lgm_tmpfsfix(); loaded_8lgm++; log(LOG_INFO, "8lgm: tmpfs fix module loaded\n"); return(0); case VDUNLOAD: return (unload(vdp, vdi)); case VDSTAT: return(0); default: return(EIO); } } static int unload(vdp, vdi) struct vddrv *vdp; struct vdioctl_unload *vdi; { if (loaded_8lgm == 0) { log(LOG_INFO, "8lgm: tmpfs fix module not loaded!\n"); return(0); } unload_8lgm_tmpfsfix(); loaded_8lgm = 0; log(LOG_INFO, "8lgm: tmpfs fix module unloaded\n"); return(0); } 8<------------------------- cut here ------------------------- ----------------------------------------------------------------------- $ echo help | mail 8lgm-fileserver@bagpuss.demon.co.uk (Fileserver help) 8lgm-bugs@bagpuss.demon.co.uk (To report security flaws) 8lgm-request@bagpuss.demon.co.uk (Request to be added to list) 8lgm@bagpuss.demon.co.uk (General enquiries)